package ar.com.fiuba.ElectronicCircuitAnalyst.domain.impl;

import static ar.com.fiuba.ElectronicCircuitAnalyst.application.api.LeadType.INPUT;

import java.util.List;

import ar.com.fiuba.ElectronicCircuitAnalyst.application.api.ConnectionDto;
import ar.com.fiuba.ElectronicCircuitAnalyst.application.api.LeadDto;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.CircuitElement;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.Connection;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.ConnectionFactory;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.Lead;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.exceptions.CircuitElementNotFoundException;

public class ConnectionFactoryImpl implements ConnectionFactory {

	public Connection makeConnection(ConnectionDto data, List<CircuitElement> circuitElements)
			throws CircuitElementNotFoundException {
		LeadDto startData = data.getStartLead();
		LeadDto endData = data.getEndLead();

		CircuitElement startElement = getElementByName(circuitElements, startData.getName());
		CircuitElement endElement = getElementByName(circuitElements, endData.getName());

		Lead endLead = resolveLead(endData, endElement);

		if (startData.getType().equals(INPUT))
			return startElement.connectToInputLead(startData.getIndex(), endLead);
		else
			return startElement.connectFromOutputLead(startData.getIndex(), endLead);
	}

	private CircuitElement getElementByName(List<CircuitElement> circuitElements, String name)
			throws CircuitElementNotFoundException {
		for (int i = 0; i < circuitElements.size(); i++)
			if (circuitElements.get(i).getName().equals(name))
				return circuitElements.get(i);
		throw new CircuitElementNotFoundException("Circuit element with name \"" + name + "\".");
	}

	private Lead resolveLead(LeadDto data, CircuitElement element) throws CircuitElementNotFoundException {
		Integer index = data.getIndex();
		try {
			if (data.getType().equals(INPUT))
				return element.getInputLeads().get(index);
			else
				return element.getOutputLeads().get(index);
		} catch (IndexOutOfBoundsException e) {
			throw new CircuitElementNotFoundException("Lead with index " + String.valueOf(index) + " not found.");
		}
	}

}
